package org.zfm.org.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.zfm.component.EmailUtil;
import org.zfm.constants.BasicConstant;
import org.zfm.org.domain.Employee;
import org.zfm.org.domain.Shop;
import org.zfm.org.domain.ShopAuditLog;
import org.zfm.org.domain.dto.AuditShopDto;
import org.zfm.org.mapper.EmployeeMapper;
import org.zfm.org.mapper.ShopMapper;
import org.zfm.org.service.IBaiduAiService;
import org.zfm.org.service.IShopAuditLogService;
import org.zfm.org.service.IShopService;
import org.zfm.base.service.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;
import org.zfm.util.data.AjaxResult;
import org.zfm.util.utils.RedisPoolUtil;
import org.zfm.util.utils.ThreadPoolUtil;
import redis.clients.jedis.Jedis;

import java.util.Date;
import java.util.Objects;
import java.util.UUID;

/**
 *  服务实现类
 * @author zara
 * @since 2022-11-01
 */
@Service
public class ShopServiceImpl extends BaseServiceImpl<Shop> implements IShopService {

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private IBaiduAiService baiduAiService;

    @Autowired
    private IShopAuditLogService shopAuditLogService;

    @Autowired
    private EmailUtil emailUtil;
    @Override
    @Transactional
    public void settlement(Shop shop) {
        Employee admin = shop.getAdmin();
        verify(shop, admin);
        //将审核和发送邮件交给其它线程来做
        ThreadPoolUtil.INSTANCE.getThreadPool().submit(new Runnable() {
            @Override
            public void run() {
                //自动审核
                ShopAuditLog log = new ShopAuditLog();//定义审核日志
                AjaxResult audit = baiduAiService.audit(shop.getName() + admin.getUsername(), null, null);
                String Note = "";
                if(audit.getSuccess()){//审核通过
                    shop.setState(BasicConstant.Shop.STATE_WAIT_ACTIVE);
                    Note = "审核通过，待验证";
                    log.setState(BasicConstant.shopAuditLog.STATE_SUCCESS);//审核通过
                    // 发送邮件 通知激活
                    sendActivateEmail(shop, admin);
                }else {
                    shop.setState(BasicConstant.Shop.STATE_REJECT_AUDIT);
                    log.setState(BasicConstant.shopAuditLog.STATE_ERROR);//设置日志状态审核驳回
                    Note = "驳回，原因："+audit.getMessage();
                    // 发送邮件 告知，店铺审核不通过
                    emailUtil.sendSimpleEmail(admin.getEmail(),shop.getName()+"店铺审核结果通知",
                            "店铺审核失败，原因是："+audit.getMessage()+" 请重试！");
                }
                shopMapper.update(shop);
                log.setAuditTime(new Date());//设置审核时间
                log.setShopId(shop.getId());//设置审核店铺id
                log.setNote(Note);
                shopAuditLogService.insert(log);
            }
        });

    }

    /**
     * 非空校验 邮箱重复校验 用户重复校验 店铺重复校验
     * @param shop 店铺
     * @param admin 店铺管理人
     */
    private void verify(Shop shop, Employee admin) {
        //非空校验
        if(StringUtils.isEmpty(shop.getName())||Objects.isNull(shop.getAddress())||
                Objects.isNull(admin)||StringUtils.isEmpty(admin.getUsername())||
                StringUtils.isEmpty(admin.getPassword())||
                StringUtils.isEmpty(admin.getConfirmPassword())||
                StringUtils.isEmpty(admin.getEmail())){
            throw new RuntimeException("信息不完整，请校验后重新申请");
        }
        // 格式校验
        //店铺校验
        if (!shop.getName().matches("[a-zA-Z\u4E00-\u9FA5]{2,8}$")){
            throw new RuntimeException("店铺名至少输入2-8之间的英文或汉字");
        }

        //电话校验
        if (!shop.getTel().matches("^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\\d{8}$")){
            throw new RuntimeException("您输入的电话格式不对，请重新输入！");
        }

        //电话校验
        if (!shop.getAdmin().getPhone().matches("^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\\d{8}$")){
            throw new RuntimeException("您输入的电话格式不对，请重新输入！");
        }

        //账号校验
        if (!shop.getAdmin().getUsername().matches("^[a-zA-Z0-9_-]{4,16}$")){
            throw new RuntimeException("请输入4到16位的账号（字母，数字，下划线，减号！");
        }

        //密码强度校验
        if (!shop.getAdmin().getPassword().matches("^.*(?=.{6,})(?=.*\\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$")){
            throw new RuntimeException("密码最少6位，包括至少1个大写字母，1个小写字母，1个数字，1个特殊字符！");
        }
        //密码和确认密码是否一致 校验
        if(!admin.getPassword().equals(admin.getConfirmPassword())){
            throw new RuntimeException("信息填写错误，请核对后再提交");
        }
        //店铺是否存在校验
        Shop shopDb = shopMapper.getByName(shop.getName());

        //判断邮箱是否以及被使用
        Employee user = employeeMapper.getByEmail(admin.getEmail());
        if(Objects.nonNull(user)){//不为空则说明该邮箱已经被使用了
            //判断已经注册的用户与当前填写用户信息是否一致
            if(admin.getUsername().equals(user.getUsername())&&
                    admin.getPassword().equals(admin.getPassword())){
                admin.setId(user.getId());
            }else {
                throw new RuntimeException("该邮箱以被注册！！！");
            }
        }
        //用户名是否存在 校验
        //如果存在，判断密码是否正确
        user = employeeMapper.getByName(admin.getUsername());
        if(Objects.nonNull(user)&& admin.getId()==null){
            if(user.getPassword().equals(admin.getPassword())){
                admin.setId(user.getId());
            }else {
                throw new RuntimeException("用户信息有误！！！");
            }
        }else{
            //店铺未激活，店铺管理员账户，也不能使用（如果店铺管理员账号还不存在的话）
            admin.setState(BasicConstant.Employee.STATE_WAIT_AUTID);
            employeeMapper.insert(admin);
        }

        //更改店铺管理人id
        shop.setAdminId(admin.getId());
        //如果已存在，判断店铺状态
        //如果店铺状态为驳回，则直接更改店铺状态
        if(Objects.nonNull(shopDb)){
            if(!shopDb.getState().equals(BasicConstant.Shop.STATE_REJECT_AUDIT))
                throw new RuntimeException("店铺已存在！！！");
            else {
                shop.setState(BasicConstant.Shop.STATE_WAIT_AUTID);
                shopMapper.update(shop);
            }
        }else {//否则就新增
            shop.setState(BasicConstant.Shop.STATE_WAIT_AUTID);
            shop.setRegisterTime(new Date());
            shopMapper.insert(shop);
        }
    }

    @Override
    @Transactional
    public void activate( String uuid) {
        Jedis jedis = RedisPoolUtil.INSTANCE.getJedis();
        String shopId = jedis.get("activateShop:" + uuid);
        if(StringUtils.isEmpty(shopId)){
            throw new RuntimeException("激活过期，请重新申请！！！");
        }
        Long id = Long.parseLong(shopId);
        Shop shop = shopMapper.selectById(id);
        shop.setState(BasicConstant.Shop.STATE_ACTIVE_SUCCESS);
        shopMapper.update(shop);
        //修改店铺管理员的状态
        Employee admin = employeeMapper.selectById(shop.getAdmin_id());
        admin.setState(BasicConstant.Employee.STATE_NORMAL);
        employeeMapper.update(admin);
    }

    /**
     * 手动审核
     * @param auditShopDto 审核信息数据包
     */
    @Override
    @Transactional
    public void auditByHand(AuditShopDto auditShopDto) {
        //格式校验


        Shop shop = auditShopDto.getShop();
        shopMapper.update(shop);
        ShopAuditLog shopAuditLog = auditShopDto.getShopAuditLog();
        shopAuditLog.setAuditTime(new Date());
        if(auditShopDto.getShop().getState().equals(BasicConstant.Shop.STATE_ACTIVE_SUCCESS)){//审核通过
            shop.setState(BasicConstant.Shop.STATE_WAIT_ACTIVE);
            //发送邮件 通知激活
            sendActivateEmail(shop, shop.getAdmin());
            shopAuditLog.setState(BasicConstant.shopAuditLog.STATE_SUCCESS);
        }else {//驳回
            shop.setState(BasicConstant.Shop.STATE_REJECT_AUDIT);
            // 发送邮件 告知，店铺审核不通过
            emailUtil.sendSimpleEmail(shop.getAdmin().getEmail(),shop.getName()+"店铺审核结果通知",
                    "店铺审核失败，原因是："+shopAuditLog.getNote()+" 请重试！");

            shopAuditLog.setState(BasicConstant.shopAuditLog.STATE_ERROR);
        }
        shopAuditLogService.insert(shopAuditLog);
    }
    // 手动审核
    /**
     * 发送限时激活邮件
     * @param shop
     * @param admin
     */
    private void sendActivateEmail(Shop shop, Employee admin) {
        UUID uuid = UUID.randomUUID();
        String content = "<h1>点击下面的按钮进行激活店铺！</h1>"+
                "<a href='http://localhost:80/shop/activate/"+uuid+"'>点击激活</a>";
        Jedis jedis = RedisPoolUtil.INSTANCE.getJedis();
        jedis.set("activateShop:"+uuid, shop.getId()+"");
        jedis.expire("activateShop:"+uuid,30*60);
        RedisPoolUtil.INSTANCE.close(jedis);
        try {
            emailUtil.sendComplexEmail(admin.getEmail(), shop.getName()+"店铺激活",
                    content,true,null);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }
}
